#pragma once

using namespace System;
using namespace NUnit::Framework;
using namespace LatoolNet;

namespace LatoolNetTest {

	[TestFixture]
	public ref class DoubleSymmetricTridiagonalMatrixTest {
	public:

		[Test]
		void TestFactorizeAndSolve() {
			
			int rownum = 5;
			int colnum = 5;

			Matrix ^a = gcnew Matrix(rownum, colnum, MatrixType::DoubleSymmetricTridiagonal);
			
			a[0, 0] = 4.0;
			a[0, 1] = -2.0;

			a[1, 1] = 10.0;
			a[1, 2] = -6.0;

			a[2, 2] = 29.0;
			a[2, 3] = 15.0;

			a[3, 3] = 25.0;
			a[3, 4] = 8.0;

			a[4, 4] = 5.0;

			Matrix ^ b = gcnew Matrix(rownum, 1);

			b[0, 0] = 6.0;
			b[1, 0] = 9.0;
			b[2, 0] = 2.0;
			b[3, 0] = 14.0;
			b[4, 0] = 7.0;

			//LUFactorization::Factorize(a);
			LinearEquation::Factorize(a);

			//LUFactorization::Solve(a, b);
			LinearEquation::Solve(a, b);

			Assert::AreEqual(4.0, a[0, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(9.0, a[1, 1], 1e-10, "Test: Solve.");
			Assert::AreEqual(25.0, a[2, 2], 1e-10, "Test: Solve.");
			Assert::AreEqual(16.0, a[3, 3], 1e-10, "Test: Solve.");
			Assert::AreEqual(1.0, a[4, 4], 1e-10, "Test: Solve.");

			Assert::AreEqual(2.5, b[0, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(2.0, b[1, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(1.0, b[2, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(-1.0, b[3, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(3.0, b[4, 0], 1e-10, "Test: Solve.");

		};

		[Test]
		void TestSolve() {
			
			int rownum = 5;
			int colnum = 5;

			Matrix ^a = gcnew Matrix(rownum, colnum, MatrixType::DoubleSymmetricTridiagonal);
			
			a[0, 0] = 4.0;
			a[0, 1] = -2.0;

			a[1, 1] = 10.0;
			a[1, 2] = -6.0;

			a[2, 2] = 29.0;
			a[2, 3] = 15.0;

			a[3, 3] = 25.0;
			a[3, 4] = 8.0;

			a[4, 4] = 5.0;

			Matrix ^ b = gcnew Matrix(rownum, 1);

			b[0, 0] = 6.0;
			b[1, 0] = 9.0;
			b[2, 0] = 2.0;
			b[3, 0] = 14.0;
			b[4, 0] = 7.0;

			//LUFactorization::Solve(a, b);
			LinearEquation::Solve(a, b);

			Assert::AreEqual(4.0, a[0, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(9.0, a[1, 1], 1e-10, "Test: Solve.");
			Assert::AreEqual(25.0, a[2, 2], 1e-10, "Test: Solve.");
			Assert::AreEqual(16.0, a[3, 3], 1e-10, "Test: Solve.");
			Assert::AreEqual(1.0, a[4, 4], 1e-10, "Test: Solve.");

			Assert::AreEqual(2.5, b[0, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(2.0, b[1, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(1.0, b[2, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(-1.0, b[3, 0], 1e-10, "Test: Solve.");
			Assert::AreEqual(3.0, b[4, 0], 1e-10, "Test: Solve.");

		};

	};
}
